package model

import (
	"errors"
	"gpt-api/framework/db"
)

/*
0 为系统账户
注意；注意；注意； amount 分为正负，正为收入，负为支出
*/

// 声明一个业务类型map
var BusinessTypes = map[string]string{
	"charge":   "BUS-CAG", // 充值类型
	"withdraw": "BUS-WTD", // 提现类型
	"consume":  "BUS-CNS", // 消费类型
	//"refund":    "BUS-RFD",    // 退款类型
	"invite-01": "BUS-INV-01", // 邀请类型
	"invite-02": "BUS-INV-02", // 邀请后充值返现类型
}

type Business struct {
	db.BaseModel
	UserId       int64   `json:"user_id" gorm:"column:user_id;type:int;not null;comment:用户ID"`
	Amount       float64 `json:"amount" gorm:"column:amount;type:decimal(10,2);not null;comment:金额"`
	Type         string  `json:"type" gorm:"column:type;type:varchar(20);not null;comment:业务类型"`
	FromId       int64   `json:"from_id" gorm:"column:from_id;type:int;default:0;comment:来源ID"`
	Comment      string  `json:"comment" gorm:"column:comment;type:varchar(255);default:'';comment:备注"`
	InviteUserId int64   `json:"invite_user_id" gorm:"column:invite_user_id;type:int;default:0;comment:被邀请用户ID"`
	// 关联被邀请用户
	InviteUser Users `json:"user" gorm:"foreignKey:ID;references:InviteUserId"`
}

func (b *Business) TableName() string {
	return "business"
}

/**
 *
 * @Description: 创建业务记录
 * @return error
 */
func (b *Business) Create(database *db.DB) error {
	return database.Create(b).Error
}

/**
 *
 * @Description: 根据用户ID分页查询业务记录
 * @return []Business
 * @return error
 */
func (b *Business) GetBusinessRecordByUserId(database *db.DB, userId int64, page, size int) ([]Business, error) {
	var record []Business
	if page <= 0 {
		page = 1
	}
	if size <= 0 {
		size = 10
	}
	err := database.Where("user_id = ?", userId).Offset((page - 1) * size).Limit(size).Find(&record).Error
	return record, err
}

// 根据用户ID分页查询邀请现金记录
func (b *Business) GetBusinessRecordByUserIdByInvite(database *db.DB, userId uint64, page, size int) ([]Business, error) {
	var record []Business
	if page <= 0 {
		page = 1
	}
	if size <= 0 {
		size = 10
	}
	err := database.Where("user_id = ?", userId).Where("type = ?", BusinessTypes["invite-02"]).Preload("InviteUser").Offset((page - 1) * size).Limit(size).Find(&record).Error
	return record, err
}

// 根据用户ID分页统计邀请次数和邀请分佣金额
func (b *Business) GetInviteCountAmountByUserId(database *db.DB, userId uint64) (int64, float64, int64, error) {
	var count int64
	var amount float64
	var score int64

	// 积分邀请总额
	err_score := database.Model(&Score{}).Select("COALESCE(SUM(score),0) AS score_total").Where("user_id = ? AND score_type = ?", userId, 4).Take(&score).Error
	if err_score != nil {
		return 0, 0, 0, err_score
	}

	// 积分邀请人数
	err_count := database.Model(&Score{}).Where("user_id = ? AND score_type = ?", userId, 4).Count(&count).Error
	if err_count != nil {
		return 0, 0, 0, err_count
	}

	// 邀请现金总额
	err_amount := database.Model(&Business{}).Select("COALESCE(SUM(amount),0) AS amount_total").Where("user_id = ? AND type = ?", userId, BusinessTypes["invite-02"]).Take(&amount).Error
	if err_amount != nil {
		return 0, 0, 0, err_amount
	}
	return count, amount, score, nil
}

/**
 *
 * @Description: 根据用户ID查询业务记录
 * @return []Business
 * @return error
 */
func (b *Business) GetBusinessRecordByUserIdAll(database *db.DB, userId int64) ([]Business, error) {
	var record []Business
	err := database.Where("user_id = ?", userId).Find(&record).Error
	return record, err
}

/**
 *
 * @Description: 充值
 * @return error
 */
func (b *Business) Charge(database *db.DB, userId int64, amount float64, comment string) error {
	if amount <= 0 {
		return errors.New("充值金额不能小于等于0")
	}

	// 先给0号用户充值，然后再给用户充值
	business := Business{
		UserId:  0,
		Amount:  amount,
		Type:    BusinessTypes["charge"],
		Comment: comment,
		FromId:  userId,
	}
	err := business.Create(database)
	if err != nil {
		return err
	}
	business.UserId = userId
	business.FromId = 0
	err = business.Create(database)
	return err
}

/**
 *
 * @Description: 提现
 * @return error
 */
func (b *Business) Withdraw(database *db.DB, userId int64, amount float64, comment string) error {
	if amount >= 0 {
		return errors.New("提现金额不能大于等于0")
	}
	// 先给用户提现，然后再给0号用户提现
	business := Business{
		UserId:  userId,
		Amount:  amount,
		Type:    BusinessTypes["withdraw"],
		Comment: comment,
		FromId:  0,
	}
	err := business.Create(database)
	if err != nil {
		return err
	}
	business.UserId = 0
	business.FromId = userId
	err = business.Create(database)
	return err
}

/**
 *
 * @Description: 消费
 * @return error
 */
func (b *Business) Consume(database *db.DB, userId int64, amount float64, comment string) error {
	if amount >= 0 {
		return errors.New("消费金额不能大于等于0")
	}
	// 先给用户消费，然后再给0号用户消费 再给0号用户收入
	business := Business{
		UserId:  userId,
		Amount:  amount,
		Type:    BusinessTypes["consume"],
		Comment: comment,
		FromId:  0,
	}
	err := business.Create(database)
	if err != nil {
		return err
	}
	business.UserId = 0
	business.FromId = userId
	err = business.Create(database)
	if err != nil {
		return err
	}
	business.Amount = -amount
	business.UserId = 0
	business.FromId = userId
	err = business.Create(database)
	return err
}
